#ifndef _RETRO_DEVICE
#define _RETRO_DEVICE

namespace Retro
{
  namespace Device
  {
    class IDevice;

    enum DeviceType
    {
      DeviceInvalid,
      DeviceAudio,
      DeviceDisplay,
    };

    enum LibraryType
    {
      LibraryInvalid,
      LibraryD3D,
      LibraryFMOD,
    };

    enum ResourceType
    {
      ResourceInvalid,
      ResourceTexture,
      ResourceFont,
      ResourceTrack,
    };

    class DLLEXPORT Resource
    {
    private:
      LibraryType                   mLibrary;
      ResourceType                  mType;
      INT                           mRefCount;
      INT                           mID;

    protected:
      Retro::Data::Resource*        mResource;

      INL Resource(LibraryType iLibrary, ResourceType iType) :
        mLibrary(iLibrary),
        mType(iType),
        mResource(NULL),
        mRefCount(1)
      {
      }

    public:
      INL LibraryType  getLibrary()
      {
        return mLibrary;
      }

      INL ResourceType getType()
      {
        return mType;
      }

      INL INT  getID()
      {
        return mID;
      }

      INL VOID setID(INT iValue)
      {
        mID = iValue;
      }

      INL INT  ref()
      {
        return ++mRefCount;
      }

      INL INT  unref()
      {
        return --mRefCount;
      }

      INL INT  getRefCount()
      {
        return mRefCount;
      }

      INL Retro::Data::Resource* getResource()
      {
        return mResource;
      }

      INL VOID setResource(Retro::Data::Resource* iRes)
      {
        mResource = iRes;
      }

      virtual BOOL initialize(IDevice* iDevice) = 0;
      virtual VOID uninitialize() = 0;

      INL virtual ~Resource()
      {
      }
    };

    class DLLEXPORT FileResource : public Resource
    {
    private:
      TCHAR       mPath[MAX_PATH];

    protected:
      INL FileResource(LibraryType iLibrary, ResourceType iType) :
        Resource(iLibrary, iType)
      {
      }

    public:
      INL PCTSTR  getPath()
      {
        return mPath;
      }

      INL VOID    setPath(PCTSTR iPath)
      {
        _tcscpy_s(mPath, MAX_PATH, iPath);
      }
    };

    class DLLEXPORT IDevice
    {
    private:
      DeviceType       mType;
      LibraryType      mLibrary;

    public:
      virtual BOOL initialize() = 0;
      virtual BOOL uninitialize() = 0;
      virtual BOOL isInitialized() = 0;

      INL DeviceType getType()
      {
        return mType;
      }

      INL LibraryType getLibrary()
      {
        return mLibrary;
      }

      INL IDevice(DeviceType iType, LibraryType iLibrary)
      {
        mType = iType;
        mLibrary = iLibrary;
      }
      INL virtual ~IDevice() {}
    };
  } // namespace Device
} // namespace Retro

#endif
